﻿using BW.WMS.WareHouseAllot;
using BW.WMS.WareHouseAllot.Interface.Doccode;
using BW.WMS.WareHouseStatistics.Page;
using BW.WMS.WareHouseStatistics.SalesReturns;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace BW.WMS.WareHouseStatistics
{
    public class SalesReturnsAppService : ApplicationService, ISalesReturnsAppService
    {
        private readonly IRepository<SalesReturnsModel, Guid> _SalesReturnsRepository;
        private readonly IRepository<SalesModel, Guid> _SalesRepository;
        private readonly IRepository<GoodsModel, Guid> _GoodsRepository;
        private readonly IDoccodeService _doccodeRepository;

        public SalesReturnsAppService(
            IRepository<SalesReturnsModel, Guid> SalesReturnsRepository,
            IRepository<SalesModel, Guid> salesRepository,
            IRepository<GoodsModel, Guid> goodsRepository,
            IDoccodeService doccodeRepository)
        {
            _SalesReturnsRepository = SalesReturnsRepository;
            _SalesRepository = salesRepository;
            _GoodsRepository = goodsRepository;
            _doccodeRepository = doccodeRepository;
        }

        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<SalesReturnsDto> CreateAsync(CreateUpdateSalesReturnsDto input)
        {
            var Sales = ObjectMapper.Map<CreateUpdateSalesReturnsDto, SalesReturnsModel>(input);

            Sales.Returncode = await _doccodeRepository.GenerateCodeAsync("销售退货");
            Sales.IsDeleted = false;

            await _SalesReturnsRepository.InsertAsync(Sales);

            return ObjectMapper.Map<SalesReturnsModel, SalesReturnsDto>(Sales);
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task DeleteAsync(Guid id)
        {
            var sales = await _SalesReturnsRepository.FirstOrDefaultAsync(x => x.Id == id && !x.IsDeleted);

            if (sales != null)
                sales.IsDeleted = true;

            await _SalesReturnsRepository.UpdateAsync(sales);
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<SalesReturnsDto> GetAsync(Guid id)
        {
            var salesReturnsQuery = await _SalesReturnsRepository.GetQueryableAsync();
            var goodsQuery = await _GoodsRepository.GetQueryableAsync();

            // 构建两表联查查询
            var query = from salesReturn in salesReturnsQuery
                        join goods in goodsQuery on salesReturn.GoodsId equals goods.Id into goodsJoin
                        from goods in goodsJoin.DefaultIfEmpty()
                        where salesReturn.Id == id && !salesReturn.IsDeleted
                        select new
                        {
                            SalesReturn = salesReturn,
                            GoodsName = goods != null ? goods.GoodsName : null,
                            GoodsCode = goods != null ? goods.GoodsCode : null
                        };

            var result = await query.FirstOrDefaultAsync();

            if (result == null)
            {
                return null;
            }

            // 手动映射为DTO
            return new SalesReturnsDto
            {
                Id = result.SalesReturn.Id,
                Returncode = result.SalesReturn.Returncode,
                Returnstate = result.SalesReturn.Returnstate,
                Returntime = result.SalesReturn.Returntime,
                Salescode = result.SalesReturn.Salescode,
                Clientname = result.SalesReturn.Clientname,
                Linkman = result.SalesReturn.Linkman,
                Phone = result.SalesReturn.Phone,
                Salesdepartment = result.SalesReturn.Salesdepartment,
                Salesperson = result.SalesReturn.Salesperson,
                Cause = result.SalesReturn.Cause,
                Desc = result.SalesReturn.Desc,
                GoodsId = result.SalesReturn.GoodsId,
                GoodsName = result.GoodsName, // 从联查结果获取货品名称
                GoodsCode = result.GoodsCode, // 从联查结果获取货品编码
                Returnnumber = result.SalesReturn.Returnnumber,
                Returnmoney = result.SalesReturn.Returnmoney,
                GoodsDesc = result.SalesReturn.GoodsDesc,
                Creator = result.SalesReturn.Creator,
                Createtime = result.SalesReturn.Createtime,
                Auditor = result.SalesReturn.Auditor,
                Audittime = result.SalesReturn.Audittime,
                Uploadattachment = result.SalesReturn.Uploadattachment,
                CreationTime = result.SalesReturn.CreationTime,
                CreatorId = result.SalesReturn.CreatorId,
                LastModificationTime = result.SalesReturn.LastModificationTime,
                LastModifierId = result.SalesReturn.LastModifierId
            };
        }
        /// <summary>
        /// 获取分页列表
        /// </summary>
        /// <param name="input">查询条件和分页参数</param>
        /// <returns>包含分页信息和数据的结果</returns>
        public async Task<PagedResultDto<SalesReturnsDto>> GetListAsync(SalesReturnsGetList input)
        {
            // 1. 获取基础查询（只查询未删除的数据）
            var salesReturnsQuery = await _SalesReturnsRepository.GetQueryableAsync();
            var goodsQuery = await _GoodsRepository.GetQueryableAsync();

            salesReturnsQuery = salesReturnsQuery.Where(x => !x.IsDeleted);

            // 2. 应用查询条件
            if (!string.IsNullOrEmpty(input.Returncode))
            {
                salesReturnsQuery = salesReturnsQuery.Where(x => x.Returncode != null && x.Returncode.Contains(input.Returncode));
            }
            if (!string.IsNullOrEmpty(input.Returnstate))
            {
                salesReturnsQuery = salesReturnsQuery.Where(x => x.Returnstate != null && x.Returnstate.Contains(input.Returnstate));
            }
            if (!string.IsNullOrEmpty(input.Clientname))
            {
                salesReturnsQuery = salesReturnsQuery.Where(x => x.Clientname != null && x.Clientname.Contains(input.Clientname));
            }
            if (input.Createtime != null)
            {
                // 按日期查询（只比较日期部分，不包含时间）
                var targetDate = input.Createtime.Value.Date;
                salesReturnsQuery = salesReturnsQuery.Where(x => x.Createtime.Date == targetDate);
            }

            // 3. 构建两表联查查询
            var query = from salesReturn in salesReturnsQuery
                        join goods in goodsQuery on salesReturn.GoodsId equals goods.Id into goodsJoin
                        from goods in goodsJoin.DefaultIfEmpty()
                        select new
                        {
                            SalesReturn = salesReturn,
                            GoodsName = goods != null ? goods.GoodsName : null,
                            GoodsCode = goods != null ? goods.GoodsCode : null
                        };

            // 4. 获取总记录数
            var totalCount = await query.CountAsync();

            // 5. 应用排序和分页
            var items = await query
                .OrderByDescending(x => x.SalesReturn.CreationTime) // 按创建时间倒序排列
                .Skip((input.PageIndex - 1) * input.PageSize)
                .Take(input.PageSize)
                .ToListAsync();

            // 6. 映射为DTO
            var dtoItems = items.Select(item => new SalesReturnsDto
            {
                Id = item.SalesReturn.Id,
                Returncode = item.SalesReturn.Returncode,
                Returnstate = item.SalesReturn.Returnstate,
                Returntime = item.SalesReturn.Returntime,
                Salescode = item.SalesReturn.Salescode,
                Clientname = item.SalesReturn.Clientname,
                Linkman = item.SalesReturn.Linkman,
                Phone = item.SalesReturn.Phone,
                Salesdepartment = item.SalesReturn.Salesdepartment,
                Salesperson = item.SalesReturn.Salesperson,
                Cause = item.SalesReturn.Cause,
                Desc = item.SalesReturn.Desc,
                GoodsId = item.SalesReturn.GoodsId,
                GoodsName = item.GoodsName, // 从联查结果获取货品名称
                GoodsCode = item.GoodsCode, // 从联查结果获取货品编码
                Returnnumber = item.SalesReturn.Returnnumber,
                Returnmoney = item.SalesReturn.Returnmoney,
                GoodsDesc = item.SalesReturn.GoodsDesc,
                Creator = item.SalesReturn.Creator,
                Createtime = item.SalesReturn.Createtime,
                Auditor = item.SalesReturn.Auditor,
                Audittime = item.SalesReturn.Audittime,
                Uploadattachment = item.SalesReturn.Uploadattachment,
                CreationTime = item.SalesReturn.CreationTime,
                CreatorId = item.SalesReturn.CreatorId,
                LastModificationTime = item.SalesReturn.LastModificationTime,
                LastModifierId = item.SalesReturn.LastModifierId
            }).ToList();

            // 7. 返回分页结果
            return PagedResultDto<SalesReturnsDto>.Create(dtoItems, totalCount, input.PageIndex, input.PageSize);
        }



        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<SalesReturnsDto> UpdateAsync(Guid id, CreateUpdateSalesReturnsDto input)
        {
            var sales = await _SalesReturnsRepository.FirstOrDefaultAsync(x => x.Id == id && !x.IsDeleted);

            if (sales == null)
            {
                return null;
            }
            ObjectMapper.Map(input, sales);

            sales.IsDeleted = false;

            await _SalesReturnsRepository.UpdateAsync(sales);

            return ObjectMapper.Map<SalesReturnsModel, SalesReturnsDto>(sales);
        }
    }
}
